package com.wnnight.wys.web.landlord;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wnnight.wys.entity.PageBean;
import com.wnnight.wys.entity.lanlord.Landlord;
import com.wnnight.wys.entity.room.Room;
import com.wnnight.wys.excelHandler.LandlordHandler;
import com.wnnight.wys.groupInterface.AddGroup;
import com.wnnight.wys.groupInterface.AlterGroup;
import com.wnnight.wys.groupInterface.RealNameGroup;
import com.wnnight.wys.security.JwtUtils;
import com.wnnight.wys.service.lanlord.LanlordService;
import com.wnnight.wys.serviceImpl.room.RoomServiceImpl;
import com.wnnight.wys.vo.LandlordVo;
import com.wnnight.wys.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.rowset.serial.SerialBlob;
import javax.validation.constraints.Min;
import javax.validation.groups.Default;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Mr.Wang
 * @ClassName: LandlordController
 * @Description: 业主controller
 * @date: 2022/8/29-16:40
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/yz")
@Validated
public class LandlordController {
    @Autowired
    private LanlordService lanlordService;

    @Autowired
    private RoomServiceImpl roomService;


    @PostMapping("/roomupdate")
    public ResultVo<?>roomupdate(long id, Integer peopleNum ) {
        Room room = new Room();
        room.setId(id);
        room.setPeopleNum(peopleNum);

        roomService.updateRoom11(room);
        return ResultVo.SUCCESS;
    }


    @PostMapping("/roomselect")
    public ResultVo<Landlord> roomselect(HttpServletRequest request){
        String jwt = request.getHeader("jwt");
        int id = (int) JwtUtils.getInfo(jwt, "id");
        List<Room> rooms = roomService.selectByLandlordId(id);
        return new ResultVo(rooms);
    }


    @PostMapping("/add")
    @PreAuthorize("hasAuthority('yz:add')")
    public ResultVo<String> add(@RequestBody @Validated(AddGroup.class) Landlord landlord){
        lanlordService.addLandlord(landlord);
        return ResultVo.SUCCESS;
    }

    @PostMapping("/update")
    @PreAuthorize("hasAuthority('yz:update')")
    public ResultVo<String> update(@RequestBody @Validated(AlterGroup.class) Landlord landlord,HttpServletRequest request){
        if(landlord.getId() == null || landlord.getId() == 0){
            String jwt = request.getHeader("jwt");
            int id = (int) JwtUtils.getInfo(jwt, "id");
            landlord.setId(id);
            lanlordService.update(landlord);
            return ResultVo.SUCCESS;
        }else{
            lanlordService.update(landlord);
            return ResultVo.SUCCESS;
        }
    }

    @PostMapping("/doupdate")
    public ResultVo<String> doUpdate(@RequestBody Landlord landlord,HttpServletRequest request){
            String jwt = request.getHeader("jwt");
            int id = (int) JwtUtils.getInfo(jwt, "id");
            landlord.setId(id);
            lanlordService.update(landlord);
            return ResultVo.SUCCESS;
    }


    @RequestMapping("/del/{id}")
    public ResultVo<String> doDelete(@PathVariable @Min(1) int id){
        lanlordService.deleteLandlord(id);
        return ResultVo.SUCCESS;
    }

    @PostMapping("/realname")
    public ResultVo<String> realName(@RequestBody @Validated(RealNameGroup.class) Landlord landlord,HttpServletRequest request){
        String jwt = request.getHeader("jwt");
        int id = (int) JwtUtils.getInfo(jwt, "id");
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode(landlord.getPassword());
        landlord.setId(id);
        landlord.setPassword(password);
        lanlordService.realName(landlord);
        return ResultVo.SUCCESS;
    }

    @PostMapping("/tologin")
    public ResultVo<String> toLogin(@RequestBody Landlord landlord,HttpServletRequest request){
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String jwt = request.getHeader("jwt");
        String account = (String) JwtUtils.getInfo(jwt, "account");
        String password = landlord.getPassword();
        int id = (int) JwtUtils.getInfo(jwt, "id");
        Landlord login = lanlordService.getInfo(id);
        if(!(account.equals(landlord.getAccount()) && bCryptPasswordEncoder.matches(password, login.getPassword()))){
            return ResultVo.ACCOUNTFAIL;
        }else{
            if("x".equalsIgnoreCase(login.getStatus())){
                return new ResultVo<>(401,"账号不可用");
            }
        }
        return ResultVo.SUCCESS;
    }

    @PostMapping("/list")
    @PreAuthorize("hasAuthority('yz:list')")
    public ResultVo<PageBean<Landlord>> list(@RequestBody @Validated({AddGroup.class, Default.class}) LandlordVo landlord){
        PageBean<List<Landlord>> pageBean = lanlordService.getByCondition(landlord);
        return new ResultVo(pageBean);
    }


    @RequestMapping("/roominfo")
    public ResultVo<Landlord> room(HttpServletRequest request){
        String jwt = request.getHeader("jwt");
        int id = (int) JwtUtils.getInfo(jwt, "id");
        Landlord landlordInfo = lanlordService.getRoomInfo(id);
        return new ResultVo(landlordInfo);
    }

    @PostMapping("/parkinfo")
    public ResultVo<Landlord> park(HttpServletRequest request){
        String jwt = request.getHeader("jwt");
        int id = (int) JwtUtils.getInfo(jwt, "id");
        Landlord landlordInfo = lanlordService.getParkInfo(id);
        log.debug("====================={}",landlordInfo);
        return new ResultVo(landlordInfo);
    }

    @RequestMapping("/carinfo")
    public ResultVo<Landlord> car(HttpServletRequest request){
        String jwt = request.getHeader("jwt");
        int id = (int) JwtUtils.getInfo(jwt, "id");
        Landlord landlordInfo = lanlordService.getCarInfo(id);
        return new ResultVo(landlordInfo);
    }

    @PostMapping("/download")
    @PreAuthorize("hasAuthority('yz:download')")
    public void download(@RequestBody @Validated LandlordVo landlordVo, HttpServletResponse response) throws IOException {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("测试", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            List<Landlord> download = lanlordService.getByDownload(landlordVo);
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), Landlord.class).registerWriteHandler(new LandlordHandler()).autoCloseStream(Boolean.FALSE).sheet("模板")
                    .doWrite(download);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.writeValue(response.getWriter(), ResultVo.ERROR);
            response.getWriter().flush();
            response.getWriter().close();
        }
    }

    @RequestMapping("/input")
    @PreAuthorize("hasAuthority('yz:add')")
    public ResultVo inputByExcel(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<Landlord> landlords = reader.readAll(Landlord.class);
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        List<Landlord> newLandlords = new ArrayList<>();
        for (Landlord l: landlords) {
            String password = bCryptPasswordEncoder.encode(l.getPassword());
            l.setPassword(password);
            newLandlords.add(l);
        }
        //将excel导入的数据保存到数据库
        lanlordService.saveBatch(newLandlords);
        return ResultVo.SUCCESS;
    }



    @PostMapping("/photo")
    public ResultVo uploadPhoto(MultipartFile file,HttpServletRequest request){
        try {
            Blob blob = new SerialBlob(file.getBytes());
            byte[] blobBytes = blob.getBytes(1, (int) blob.length());
//            file.transferTo(new File("F://testfile/"+file.getOriginalFilename()));
            Landlord landlord = new Landlord();
            String jwt = request.getHeader("jwt");
            int id = (int) JwtUtils.getInfo(jwt, "id");
            landlord.setId(id);
            landlord.setImg(blobBytes);
            lanlordService.update(landlord);
            return new ResultVo(200,"ok",file.getOriginalFilename());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    @RequestMapping("/getphoto/{id}")
    public byte[] getPhoto(@PathVariable @Min(1) int id,HttpServletRequest request){
//        String jwt = request.getHeader("jwt");
//        int id = (int) JwtUtils.getInfo(jwt, "id");
        //ToDo 也可根据JWT获取业主的id传入
        Landlord landlord = lanlordService.getImg(id);
        return landlord.getImg();
    }

    @RequestMapping("/num")
    public ResultVo getNum(){
        return new ResultVo(lanlordService.getNumByColumn("status","y"));
    }
}
